package com.rockkang.gp.homework.proxy.example.cglib;

import com.rockkang.gp.homework.proxy.example.entity.Person;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibMeiPo implements MethodInterceptor {

    private static final CglibMeiPo CGLIB_MEI_PO = new CglibMeiPo();
    private CglibMeiPo(){super();}

    public static Object getInstance(Class<? extends Person> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(CGLIB_MEI_PO);
        return enhancer.create();
    }

    public static Object getInstance(Class<? extends Person> clazz, String name) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(CGLIB_MEI_PO);
        return enhancer.create(new Class[]{String.class}, new Object[]{name});
    }

    public static <T extends Person>T getInstance (Class<T> clazz, String name, int age) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(CGLIB_MEI_PO);
        return (T)enhancer.create(new Class[]{String.class, int.class}, new Object[]{name, age});
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("---------intercept----------");
        before(o, method, objects, methodProxy);
//        Object obj = method.invoke(o, objects);
        Object obj = methodProxy.invokeSuper(o, objects);
        after(o, method, objects, methodProxy);
        return obj;
    }

    private void before(Object o, Method method, Object[] objects, MethodProxy methodProxy) {
        System.out.println("----------------cglib before----------------");
//        System.out.println(o.getClass());
//        System.out.println(method.getClass());
//        System.out.println(method.getName());
//        System.out.println(methodProxy.getClass());
//        System.out.println(methodProxy.getSuperName());
//        System.out.println("----------------cglib before end----------------");
    }

    private void after(Object o, Method method, Object[] objects, MethodProxy methodProxy) {
        System.out.println("----------------cglib after----------------");
    }
}
